<template>
  <view>
    <uni-popup ref="popup" @maskClick="close">
      <view class="popup-box">
        <view class="title">
          <view class="tabs-box" v-if="mode == 'all'">
            <view
              v-for="(item, index) in tabs"
              :key="index"
              class="tabs-item"
              @click="tabChange(index)"
              :class="{ 'tabs-check': index == tabIndex }"
            >
              <text class="item-text">{{ item }}</text>
            </view>
          </view>
          <view v-else class="title-text">
            <text class="text">{{
              mode == "multiple" ? "日期筛选" : "月份选择"
            }}</text>
          </view>
          <uni-icons
            type="closeempty"
            class="close"
            size="16"
            @click="close"
          ></uni-icons>
        </view>

        <view class="options-box" v-if="tabIndex">
          <view class="flex row-between">
            <view
              v-for="(item, index) in options"
              :key="index"
              class="option"
              @click="optionSelect(index)"
              :class="{ 'option-check': opIndex == index }"
            >
              <text class="option-text">{{ item }}</text>
            </view>
          </view>
          <view class="flex row-between" style="margin-top: 40rpx">
            <view
              class="option"
              :class="{ 'option-check': op1Index == 0 }"
              style="width: 320rpx; padding-left: 0; padding-right: 0"
              @click="optionChange(0)"
            >
              <text class="option-text">{{ startDate }}</text>
            </view>
            <view
              style="width: 18rpx; height: 2rpx; background: #7b8686"
            ></view>
            <view
              class="option"
              :class="{ 'option-check': op1Index == 1 }"
              style="width: 320rpx; padding-left: 0; padding-right: 0"
              @click="optionChange(1)"
            >
              <text class="option-text">{{ endDate }}</text>
            </view>
          </view>
        </view>
        <view class="picker-body">
          <picker-view
            class="picker-view"
            indicator-style="height:38px;background: rgba(0,0,0,.03);border:none;"
            :value="valueArr"
            @change="change"
            @touchend="touchend"
          >
            <picker-view-column v-if="params.year">
              <view
                class="column-item"
                v-for="(item, index) in years"
                :key="index"
              >
                <text class="column-item-text">{{ item }}年</text>
              </view>
            </picker-view-column>
            <picker-view-column v-if="params.month">
              <view
                class="column-item"
                v-for="(item, index) in months"
                :key="index"
              >
                <text class="column-item-text">{{ formatNumber(item) }}月</text>
              </view>
            </picker-view-column>
            <picker-view-column v-if="params.day">
              <view
                class="column-item"
                v-for="(item, index) in days"
                :key="index"
              >
                <text class="column-item-text">{{ formatNumber(item) }}日</text>
              </view>
            </picker-view-column>
          </picker-view>
        </view>
        <view class="bottom">
          <view class="h-btn h-btn-line" @click="reset">
            <text style="color: #333">重置</text>
          </view>
          <view class="h-btn" @click="getResult">
            <text style="color: #fff">确定</text>
          </view>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

<script>
import timeFormat from "../../js/timeFormat.js";
export default {
  props: {
    // picker中需要显示的参数
    params: {
      type: Object,
      default() {
        return {
          year: true,
          month: true,
          day: true,
        };
      },
    },
    // 默认显示的时间，2025-07-02 || 2025-07-02 13:01:00 || 2025/07/02
    defaultTime: {
      type: String,
      default: timeFormat(new Date(), "yyyy-mm-dd"),
    },
    // 自定义时间选项模式month:月 day:天
    optionMode: {
      type: String,
      default: "month",
    },
    //选择器模式 single:单月 multiple:多月 all:都包括(暂时有bug 勿用)
    mode: {
      type: String,
      default: "all",
    },
    endTime: {
      type: String,
      default: timeFormat(new Date(), "yyyy-mm-dd"),
    },
  },
  data() {
    return {
      timeFormat,
      years: [],
      months: [],
      days: [],
      hours: [],
      minutes: [],
      seconds: [],
      valueArr: [],
      yearKey: 0,
      monthKey: 0,
      dayKey: 0,
      hourKey: 0,
      minuteKey: 0,
      secondy: 0,
      date: "",
      startDate: "",
      endDate: "",
      time: {},
      end_time: {},
      tabs: ["月份选择", "自定义时间"],
      tabIndex: 0,
      opIndex: -1,
      op1Index: 0,
      options: ["近三月", "近半年", "近一年"],
      fmt: "yyyy-mm-dd",
      isClick: false,
    };
  },
  mounted() {
    this.init();
  },
  watch: {
    "time.year"(val, oval) {
      if (this.params.month && oval) {
        this.setMonths();
        // this.setDays()
      }
      if (this.params.day && oval) {
        this.setDays();
      }
    },
    "time.month"(val, oval) {
      if (this.params.day && oval) {
        this.setDays();
      }
    },
  },
  methods: {
    init() {
      this.valueArr = [];
      this.tabIndex = this.mode == "multiple" ? 1 : 0;
      // 初始化默认选中时间
      this.time = this.initTimeValue(this.defaultTime);
      // 初始化截止时间
      this.end_time = this.initTimeValue(this.endTime);

      let fmt = [];
      if (this.optionMode == "day") {
        this.options = ["近3天", "近7天", "近15天"];
      }
      if (this.params.year) {
        this.valueArr.push(0);
        this.yearKey = this.valueArr.length - 1;
        this.setYears();
        fmt.push("yyyy");
      }
      if (this.params.month) {
        this.valueArr.push(0);
        this.monthKey = this.valueArr.length - 1;
        this.setMonths();
        fmt.push("mm");
      }
      if (this.params.day) {
        this.valueArr.push(0);
        this.dayKey = this.valueArr.length - 1;
        this.setDays();
        fmt.push("dd");
      }
      this.fmt = fmt.join("-");
      //初始化显示日期
      this.date =
        this.startDate =
        this.endDate =
          this.timeFormat(
            new Date(this.defaultTime.replace(/\-/g, "/")),
            this.fmt
          );
      // console.log(this.valueArr);
    },
    initDate() {
      if (this.params.year) {
        this.setYears();
      }
      if (this.params.month) {
        this.setMonths();
      }
      if (this.params.day) {
        this.setDays();
      }
    },
    open() {
      uni.hideTabBar({
        animation: true,
      });
      this.$refs.popup.open("bottom");
    },
    close() {
      uni.showTabBar({
        animation: true,
      });
      this.$refs.popup.close();
    },
    //点击重置
    reset() {
      this.close();
      this.init();
      this.$emit("reset");
    },
    // 点击确定
    getResult() {
      let result = {};
      let { date, time } = this;
      if (this.tabIndex) {
        let change_date = this.endDate;
        let start_time = {};
        let end_time = {};
        if (
          this.startDate.replace(/\-/g, "/") > this.endDate.replace(/\-/g, "/")
        ) {
          this.endDate = this.startDate;
          this.startDate = change_date;
          this.optionChange(0);
        }
        // console.log(this.startDate, this.endDate);
        if (this.params.year) {
          start_time.year = this.formatNumber(
            this.initTimeValue(this.startDate).year || 0
          );
          end_time.year = this.formatNumber(
            this.initTimeValue(this.endDate).year || 0
          );
        }
        if (this.params.month) {
          start_time.month = this.formatNumber(
            this.initTimeValue(this.startDate).month || 0
          );
          end_time.month = this.formatNumber(
            this.initTimeValue(this.endDate).month || 0
          );
        }
        if (this.params.day) {
          start_time.day = this.formatNumber(
            this.initTimeValue(this.startDate).day || 0
          );
          end_time.day = this.formatNumber(
            this.initTimeValue(this.endDate).day || 0
          );
        }
        start_time.time = this.startDate;
        end_time.time = this.endDate;
        start_time.timestamp = new Date(
          this.startDate.replace(/\-/g, "/")
        ).getTime();
        end_time.timestamp = new Date(
          this.endDate.replace(/\-/g, "/")
        ).getTime();
        result = {
          start_time,
          end_time,
        };
      } else {
        if (this.params.year) result.year = this.formatNumber(time.year || 0);
        if (this.params.month)
          result.month = this.formatNumber(time.month || 0);
        if (this.params.day) result.day = this.formatNumber(time.day || 0);
        result.time = date;
        result.timestamp = new Date(date.replace(/\-/g, "/")).getTime();
        // console.log(result, date);
      }
      this.$emit("confirm", result);
      this.close();
    },
    // 设置picker的某一列值
    setYears() {
      let { time, end_time } = this;
      let { year } = end_time;
      // 获取年份集合
      this.years = this.generateArray(1950, year);
      // 设置this.valueArr某一项的值，是为了让picker预选中某一个值
      setTimeout(() => {
        this.valueArr.splice(
          this.yearKey,
          1,
          this.getIndex(this.years, time.year)
        );
      }, 10);
    },
    setMonths() {
      let { time, end_time } = this;
      let { year, month } = end_time;
      if (year == time.year && this.params.year) {
        this.months = this.generateArray(1, month);
      } else {
        this.months = this.generateArray(1, 12);
      }
      if (time.month > this.months.length) this.time.month = this.months.length;
      //解决微信小程序初始化问题
      setTimeout(() => {
        this.valueArr.splice(
          this.monthKey,
          1,
          this.getIndex(this.months, time.month)
        );
      }, 10);
    },
    setDays() {
      let { time, end_time } = this;
      let { year, month, day } = end_time;
      let totalDays = new Date(time.year, time.month, 0).getDate();
      if (year == time.year && month == time.month && this.params.year) {
        this.days = this.generateArray(1, day);
      } else {
        this.days = this.generateArray(1, totalDays);
      }
      if (time.day > this.days.length) this.time.day = this.days.length;
      setTimeout(() => {
        this.valueArr.splice(
          this.dayKey,
          1,
          this.getIndex(this.days, time.day)
        );
      }, 10);
    },
    // 生成递进的数组
    generateArray: function (start, end) {
      // 转为数值格式，否则用户给end-year等传递字符串值时，下面的end+1会导致字符串拼接，而不是相加
      start = Number(start);
      end = Number(end);
      end = end > start ? end : start;
      // 生成数组，获取其中的索引，并剪出来
      return [...Array(end + 1).keys()].slice(start);
    },
    getIndex: function (arr, val) {
      let index = arr.indexOf(val);
      // 如果index为-1(即找不到index值)，~(-1)=-(-1)-1=0，导致条件不成立
      return ~index ? index : 0;
    },
    //日期时间处理
    initTimeValue(defaultTime) {
      // 格式化时间，在IE浏览器(uni不存在此情况)，无法识别日期间的"-"间隔符号
      let fdate = defaultTime.replace(/\-/g, "/");
      fdate = fdate && fdate.indexOf("/") == -1 ? `2020/01/01 ${fdate}` : fdate;
      let time = null;
      if (fdate) time = new Date(fdate);
      else time = new Date();
      // 获取年日月时分秒
      return {
        year: time.getFullYear(),
        month: Number(time.getMonth()) + 1,
        day: time.getDate(),
      };
    },
    // 小于10前面补0，用于月份，日期，时分秒等
    formatNumber(num) {
      return +num < 10 ? "0" + num : String(num);
    },
    // 获取时间戳
    getTimestamp(date) {
      // yyyy-mm-dd为安卓写法，不支持iOS，需要使用"/"分隔，才能二者兼容
      let time = date.year + "/" + date.month + "/" + (date.day || "01");
      return new Date(time).getTime();
    },
    touchend(e) {
      this.opIndex = -1;
    },
    // 用户更改picker的列选项
    change(e) {
      this.valueArr = e.detail.value;
      let i = 0;
      let time = {
        year: 0,
        month: 0,
        day: 0,
      };
      if (this.params.year) time.year = this.years[this.valueArr[i++]];
      if (this.params.month) time.month = this.months[this.valueArr[i++]];
      if (this.params.day) time.day = this.days[this.valueArr[i++]];
      this.time = time;
      let date = this.timeFormat(this.getTimestamp(time), this.fmt);
      //自定义时间段
      if (this.tabIndex) {
        if (this.op1Index) {
          this.endDate = date;
        } else {
          this.startDate = date;
        }
      } else {
        //月份选择
        this.date = date;
      }
    },
    tabChange(i) {
      this.tabIndex = i;
      if (!i) {
        this.time = this.initTimeValue(this.date);
        this.initDate();
      } else {
        this.optionChange(this.op1Index);
      }
    },
    //选择快捷时间段
    optionSelect(i) {
      this.opIndex = i;
      let end_time = new Date();
      let start_time;
      switch (i) {
        case 0: //近三月，近三天
          if (this.optionMode == "day") {
            start_time = end_time.setDate(new Date(end_time).getDate() - 3);
          } else {
            start_time = end_time.setMonth(new Date(end_time).getMonth() - 3);
          }
          break;
        case 1: //近半年，近七天
          if (this.optionMode == "day") {
            start_time = end_time.setDate(new Date(end_time).getDate() - 7);
          } else {
            start_time = end_time.setMonth(new Date(end_time).getMonth() - 6);
          }
          break;
        case 2: //近一年，近十五天
          if (this.optionMode == "day") {
            start_time = end_time.setDate(new Date(end_time).getDate() - 15);
          } else {
            start_time = end_time.setMonth(new Date(end_time).getMonth() - 12);
          }
          break;
      }
      this.endDate = this.timeFormat(new Date(), this.fmt);
      this.startDate = this.timeFormat(start_time, this.fmt);
      this.time = this.initTimeValue(
        this.op1Index ? this.endDate : this.startDate
      );
      this.initDate();
    },
    //起始时间、截至时间切换
    optionChange(i) {
      this.op1Index = i;
      this.time = this.initTimeValue(i ? this.endDate : this.startDate);
      this.initDate();
    },
  },
};
</script>

<style lang="scss" scoped>
.flex {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.row-between {
  justify-content: space-between;
}

.popup-box {
  background-color: #fff;
  border-radius: 24rpx 24rpx 0 0;
  padding-bottom: 40rpx;
}

.picker-body {
  overflow: hidden;
  padding: 32rpx 40rpx;
}

.picker-view {
  height: 380rpx;
  width: 670rpx;
}

.column-item {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32rpx;
  color: #888;
  // height: 76rpx;
  height: 38px;
}

.column-item-text {
  line-height: 38px;
  height: 38px;
  font-size: 32rpx;
}

.title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-direction: row;
  position: relative;

  .close {
    position: relative;
    right: 50rpx;
  }

  .title-text {
    width: 750rpx;
    padding: 24rpx 0;
    display: flex;
    flex-direction: row;
    justify-content: center;

    .text {
      font-size: 32rpx;
      font-weight: 600;
    }
  }
}

.tabs-box {
  width: 750rpx;
  display: flex;
  flex-direction: row;
  padding: 0 50rpx 0 32rpx;
  align-items: center;
  border-bottom: 2rpx solid rgba(225, 225, 225, 0.5);

  .tabs-item {
    padding: 24rpx 0 22rpx 0;
    margin-right: 84rpx;
    border-bottom: 4rpx solid #fff;
  }

  .item-text {
    font-size: 28rpx;
  }
}

.tabs-check {
  border-bottom: 4rpx solid #40ae36 !important;

  .item-text {
    color: #40ae36;
  }
}

.bottom {
  padding: 0 32rpx 32rpx;
  display: flex;
  align-items: center;
  flex-direction: row;

  .h-btn {
    flex: 1;
    height: 80rpx;
    background: #40AE36;
    border-radius: 16rpx;
    display: flex;
    align-items: center;
    border: 2rpx solid #40AE36;
    justify-content: center;
  }

  .h-btn-line {
    background: #fff;
    border: 2rpx solid #e1e7ec;
    margin-right: 42rpx;
  }
}

.option {
  padding: 14rpx 58rpx;
  font-size: 28rpx;
  border-radius: 16rpx;
  background: #f4f7f8;
  border: 3rpx solid #f4f7f8;
  display: flex;
  justify-content: center;
  flex-direction: row;

  .option-text {
    font-size: 28rpx;
    font-weight: 500;
    color: #333333;
    line-height: 40rpx;
  }
}

.option-check {
  background: #f5ffff;
  border-radius: 16rpx;
  border: 3rpx solid #40AE36;

  .option-text {
    color: #40AE36;
  }
}

.options-box {
  padding: 32rpx;
  transition-property: height;
  transition-duration: 0.4s;
}
</style>